/*
 * src/syntax/syntax.c
 *
 * Harry Wei <harryxiyou@gmail.com>
 * 
 * The main control portions for syntax.
 */
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "common.h"
#include "cp_ctrl.h"

static int handle_pro(struct la *ctrl, char *pro, int *i) {
	g_message("enter func %s", __func__);
	g_message("%s -- pro is [%s], i is [%d]", __func__, pro, *i);
	gchar **v = NULL;
	v = g_strsplit(pro, "@", 0);
	g_message("%s -- last one is %s", __func__, v[g_strv_length(v) - 1]);
	while (1) {
		if (0 == g_strcmp0(v[g_strv_length(v) - 1], ctrl->v[(*i)])) {
			break;
		}
		(*i) += 1;
	}
	g_message("leave func %s", __func__);
	return 0;
}

int syntax(struct la *ctrl) {
	g_message("enter func %s", __func__);
	g_message("Test stack");
#if 1
	//rm_element(ctrl);
	struct stack *tmp = ctrl->ss->next;
//	while (NULL != tmp) {
//		g_message("%s -- %s", __func__, tmp->ch);
//		tmp = tmp->next;
//	}
	int i = 0;
	for (i = 0; i < ctrl->v_len; i++) {
		g_message("%s -- %s", __func__, ctrl->v[i]);
	}
#endif
	i = 1;
	int j = 0;
	while (1) {	/* reduce -- combine ll_table and symbol stack */
		if (i > ctrl->v_len) {
			handle_error();
			break;
		}
		if (0 == g_strcmp0(tmp->ch, "#") && 
				0 == g_strcmp0(ctrl->v[i], "@@##$$")) {
			g_print("The Input String is okay...\n");
			break;
		}
		if (0 == g_strcmp0(tmp->ch, "#") || 
				0 == g_strcmp0(ctrl->v[i], "@@##$$")) {
			g_print("The Input String Has Errors...\n");
			handle_error();
			break;
		}
		g_message("%s -- i is %d", __func__, i);
		sleep(1);
		struct ll_table *_tmp = ctrl->analyse_table;
		for (j = 0; j < ctrl->ll_len; j++) {
			g_message("%s -- j is %d", __func__, j);
			sleep(1);
			g_message("%s -- vn is [%s], vt is [%s], v[%d] is [%s], stack is [%s]", __func__, 
												_tmp->vn, _tmp->vt, 
												i, ctrl->v[i],
												tmp->ch);
			if ((0 == g_strcmp0(_tmp->vn, tmp->ch)) && 
					(0 == g_strcmp0(_tmp->vt, ctrl->v[i]))) {
				if (1 == _tmp->is_last) {
					rm_element(ctrl);
					i++;
					tmp = ctrl->ss->next;
					break;
				} else {
					handle_pro(ctrl, _tmp->pro, &i);
					if (i > ctrl->v_len) {
						handle_error();
						break;
					}
					i += 1;
					rm_element(ctrl);
					tmp = ctrl->ss->next;
					break;
				}
			}
			_tmp++;
		}
	}
	g_message("leave func %s", __func__);
	return 0;
}
